package com.xiaomaoguai.fcp.pre.kepler.tddl.config;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.taobao.tddl.client.jdbc.TDataSource;
import com.taobao.tddl.client.sequence.impl.GroupSequenceDao;
import com.xiaomaoguai.fcp.pre.kepler.tddl.sequence.Sequence;
import com.xiaomaoguai.fcp.pre.kepler.tddl.sequence.TddlSequenceUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.util.Optional;

/**
 * TDDL 自动配置，支持单个数据库
 *
 * @author chenyao
 * @since 2018年5月17日 下午1:37:48
 */
@Slf4j
@Configuration
@AutoConfigureBefore(MybatisPlusAutoConfiguration.class)
@EnableConfigurationProperties({TddlProperties.class})
@ConditionalOnProperty(prefix = TddlConstants.CONFIG_PREFIX, value = "enabled", matchIfMissing = false)
public class TddlAutoConfiguration {

	private final TddlProperties properties;

	/**
	 * 初始化 TDDL 自动配置
	 *
	 * @param properties TDDL 属性配置
	 */
	public TddlAutoConfiguration(TddlProperties properties) {
		this.properties = properties;
		if (log.isInfoEnabled()) {
			log.info("init TDDL auto configuration, properties: {}", JSON.toJSONString(properties));
		}
	}

	/**
	 * 初始化 TDDL 数据源
	 *
	 * @return TDDL 数据源
	 */
	@Primary
	@Bean(initMethod = "init")
	public TDataSource dataSource() {
		TDataSource dataSource = new TDataSource();
		dataSource.setAppName(this.properties.getAppName());
		dataSource.setDynamicRule(true);
		return dataSource;
	}

	/**
	 * 初始化数据源事务管理者
	 *
	 * @param dataSource 数据源
	 * @return 数据源事务管理者
	 */
	@Bean
	@ConditionalOnMissingBean
	public DataSourceTransactionManager transactionManager(DataSource dataSource) {
		DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
		dataSourceTransactionManager.setDataSource(dataSource);
		return dataSourceTransactionManager;
	}

	/**
	 * 初始化事务管理模版
	 *
	 * @param transactionManager 数据源事务管理者
	 * @return 事务管理模版
	 */
	@Bean
	@ConditionalOnMissingBean
	public TransactionTemplate transactionTemplate(DataSourceTransactionManager transactionManager) {
		TransactionTemplate template = new TransactionTemplate();
		template.setTransactionManager(transactionManager);
		return template;
	}

	/**
	 * 初始化默认的 TDDL GroupSequenceDao 实例对象
	 *
	 * @return TDDL GroupSequenceDao 实例对象
	 */
	@Primary
	@ConditionalOnProperty(prefix = TddlConstants.CONFIG_PREFIX, value = "group-name", matchIfMissing = false)
	@ConditionalOnMissingBean
	@Bean(initMethod = "init")
	public GroupSequenceDao sequenceDao() {
		return TddlSequenceUtils.buildSequenceDao(this.properties, false);
	}

	/**
	 * 初始化表的 TDDL sequence，用于生成主键id
	 *
	 * @param sequenceDao        TDDL GroupSequenceDao 实例对象
	 * @param applicationContext Spring Application Context
	 * @return 空对象
	 */
	@Bean
	@ConditionalOnBean(GroupSequenceDao.class)
	@ConditionalOnMissingBean(name = "initTddlSequence")
	public Optional<Sequence> initTddlSequence(GroupSequenceDao sequenceDao, ApplicationContext applicationContext) {
//		TddlSequenceUtils.initTddlSequence(TableMetaObject.getSequenceBeanMap().values(), sequenceDao,
//				applicationContext);
		return Optional.empty();
	}

}
